<script setup lang="ts">
import { h, ref, watch } from 'vue';
import { ElDialog, ElNotification } from 'element-plus';
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt';

const publicKey =
  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAooxomrujIP9vcxxNmS+Q1xxnaoxAfluwFvDR3+G+p84QMsePXDD67cLjJ+7n+79u2xoG7fVvDnzHDW+X5D/0/Dv9ajUaBpFQl3jqKwRiP3Lrx08seYzWIWDGHEjurbZrWGHRJNdoM7tEQPdPZftZC6iOm7kSjDIDiuqaIh9g3hqFSVQ5r15Dvae6qtREo1nDWKsf3tH6nkvVD2pIh3TBJUoGdfbPqnw/tNvzhwOX9tg7NjhZ8Yet1ctVt297G5HCwPSIBjhUKEtLYLk/8scPrzXnQpAU05m5WnHfDhfvvG2xoVXckveNvZhv6lvxTZqRkUBOI1pU16U9Tz4aDpCU7QIDAQAB";


const props = defineProps<{ courseId: number }>();

const visible = ref(false);

const totalCourseCount = ref(0);
const totalPageSize = ref(0);

defineExpose({
  visible
});

const serializeAndSignParams = (params: any, sort: boolean = true) => {
  let serializedString = '';
  const keys = sort ? Object.keys(params).sort() : Object.keys(params);

  for (const key of keys) {
    if (params[key] !== null && params[key] !== undefined) {
      serializedString += `${key}=${params[key]}&`;
    }
  }
  // 移除末尾的 '&'
  // serializedString = serializedString.slice(0, -1);

  console.log("序列化后的参数字符串:", serializedString); // 调试用

  // 使用 CryptoJS 计算参数的 MD5 哈希值作为签名[6](@ref)
  const signature = encrypt(publicKey, CryptoJS.MD5(serializedString).toString());

  return serializedString + `&sign=${encodeURIComponent(signature)}`;
}

// 生成随机字符串的方法（可直接使用简化后的函数）
function generateRandomString(length = 32) {
  const characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  let result = '';
  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * characters.length);
    result += characters[randomIndex];
  }
  return result;
}

const encrypt = (publicKey: string, data: string) => {
  // 创建一个 JSEncrypt 实例
  const encryptor = new JSEncrypt();
  encryptor.setPublicKey(publicKey);
  const encryptedData = encryptor.encrypt(data);
  return encryptedData;
}

// 监听 courseId 变化
watch(() => props.courseId, async (newCourseId) => {
  if (newCourseId) {
    visible.value = true;
    console.log("课程ID已更新:", newCourseId);

    const params = {
      companyId: localStorage.getItem('companyId') || 0,
      currentPage: 1,
      from: "WEB",
      subjectId: "",
      id: props.courseId,
      name: "",
      organizationId: localStorage.getItem('organizationId') || 0,
      pageSize: 8,
      randomStr: generateRandomString(),
      token: localStorage.getItem('t') || "",
      timestamp: Math.floor(Date.now() / 1000),
      status: 1,
      total: 0
    }

    const queryString = serializeAndSignParams(params);
    console.log("序列化后的参数字符串:", queryString);

    const response = await fetch(`https://campus.chinaunicom.cn/training/app/themeColumn/getMyAreaInfoCourse?${queryString}`, {
      "method": "POST"
    });
    const data = await response.json();
    totalCourseCount.value = data.entity.page.totalResultSize || 0;
    totalPageSize.value = data.entity.page.totalPageSize || 0;

    // 处理课程数据
    const courses = data.entity.courseList || [];

    for (let i = 2; i <= totalPageSize.value; i++) {
      params.currentPage = i;
      const queryString = serializeAndSignParams(params);
      const response = await fetch(`https://campus.chinaunicom.cn/training/app/themeColumn/getMyAreaInfoCourse?${queryString}`, {
        "method": "POST"
      });
      const data = await response.json();
      courses.push(...data.entity.courseList);
    }

    console.log("所有课程数据:", courses); // 在这里处理所有课程数据

    for (const course of courses) {
      console.log("处理课程:", course);
      // 获取 kPointId
      const queryString = serializeAndSignParams({
        "token": localStorage.getItem('t') || "",
        "timestamp": Math.floor(Date.now() / 1000),
        "companyId": localStorage.getItem('companyId') || 0,
        "from": "WEB",
        "organizationId": localStorage.getItem('organizationId') || 0,
        "randomStr": generateRandomString(),
        "kpointId": 0
      })
      const response = await fetch(`https://campus.chinaunicom.cn/training/app/front/playkpoint/${course.id}?${queryString}`, {
        "method": "POST"
      });
      const data = await response.json();
      // TODO: 多子视频支持
      const kPointId = data.entity.kpoint.id;
      let playTime = data.entity.kpoint.userPlayTime || 0;
      const totalPlayTime = Math.max(course.totalPlayTime, data.entity.course.totalPhase) || 10800;
      console.log(course.name, course.id, kPointId, playTime, totalPlayTime);

      // 暂停 1 秒，避免请求过快
      await new Promise(resolve => setTimeout(resolve, 1000));

      for (playTime; playTime < totalPlayTime; playTime += 123) {
        const queryPlayString = serializeAndSignParams({
          "token": localStorage.getItem('t') || "",
          "timestamp": Math.floor(Date.now() / 1000),
          "companyId": localStorage.getItem('companyId') || 0,
          "from": "WEB",
          "organizationId": localStorage.getItem('organizationId') || 0,
          "randomStr": generateRandomString(),
          "type": "playback",
          "kpointId": kPointId,
          "courseId": course.id,
          "breakpoint": playTime,
          "studyTime": playTime + 123,
          "accrualType": 1,
        }, true)
        const playResponse = await fetch(`https://campus.chinaunicom.cn/training/app/course/playtimeV2?${queryPlayString}`, {
          "method": "POST"
        });
        const playData = await playResponse.json();
        console.log(`课程 ${course.name} (${course.id}) 已更新播放时间至 ${playTime + 123} 秒`, playData);
        if (playData.message === "修改失败，超出进度范围") {
          break;
        }
        ElNotification({
          title: 'Newicom',
          message: h('i', { style: 'color: teal' }, `课程 ${course.name} (${course.id}) 已更新播放时间至 ${playTime + 123} 秒`),
        })
      }
    }
  }
}, { immediate: true });

</script>

<template>
  <ElDialog v-model="visible" title="课程详情">
    <p>课程ID: {{ courseId }}</p>
    <p>课程总数: {{ totalCourseCount }}</p>
    <p>共计课程页数: {{ totalPageSize }}</p>
  </ElDialog>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>
